<template>
  <n-modal
    :block-scroll="false"
    id="basic-modal"
    :style="{ width: getBindValue.width + 'px' }"
    v-bind="getBindValue"
    v-model:show="isModal"
    @close="onCloseModal"
  >
    <template #header>
      <div class="w-full cursor-move" id="basic-modal-bar">{{ getBindValue.title }}</div>
    </template>
    <template #default>
      <slot name="default"></slot>
    </template>
    <template #action v-if="!$slots.action">
      <n-space>
        <n-button @click="closeModal">{{
          $t(`common.button.${confirmBtnShow ? 'cancel' : 'close'}`)
        }}</n-button>
        <n-button
          v-if="confirmBtnShow"
          type="primary"
          :loading="subLoading"
          @click="handleSubmit"
          >{{ $t(`common.button.${subBtuText}`) }}</n-button
        >
      </n-space>
    </template>
    <template v-else #action>
      <slot name="action"></slot>
    </template>
  </n-modal>
</template>

<script lang="ts" setup>
  import { getCurrentInstance, ref, nextTick, unref, computed, useAttrs } from 'vue';
  import { basicProps } from './props';
  import startDrag from '@/utils/Drag';
  import { deepMerge } from '@/utils';
  import { FormProps } from '@/components/DFForm';
  import { ModalProps, ModalMethods } from './type';
  import { debounce } from 'lodash';
  import { useMixins } from '@/hooks/useMixins';
  import { t } from '@/i18n';

  const { language, routerPage } = useMixins();

  const attrs = useAttrs();
  const props = defineProps({ ...basicProps });
  const emit = defineEmits(['on-close', 'on-ok', 'register']);

  const propsRef = ref<Partial<ModalProps> | null>(null);

  const isModal = ref(false);
  const subLoading = ref(false);

  const title = ref('');

  const getProps = computed((): FormProps => {
    return { ...props, ...(unref(propsRef) as any) };
  });

  const confirmBtnShow = computed(() => {
    const { confirmBtnShow } = propsRef.value as any;

    // console.log(props);

    return confirmBtnShow || props.confirmBtnShow;
  });

  const subBtuText = computed(() => {
    const { subBtuText } = propsRef.value as any;

    return subBtuText || props.subBtuText;
  });

  async function setProps(modalProps: Partial<ModalProps>): Promise<void> {
    propsRef.value = deepMerge(unref(propsRef) || ({} as any), modalProps);
  }

  const getBindValue: any = computed(() => {
    const obj = {
      ...attrs,
      ...unref(getProps),
      ...unref(propsRef),
    };

    if (title.value !== '') {
      obj['title'] = title.value;
    }

    return obj;
  });

  function setSubLoading(status: boolean) {
    subLoading.value = status;
  }

  function openModal(type, titleText = '') {
    const { dialogTypeTitle = '' } = getBindValue.value;

    subLoading.value = false;

    if (titleText) {
      title.value = titleText;
    } else {
      if (type) {
        title.value = `${t('common.button.' + type)}`;
      }

      if (language.value === 'zh') {
        if (dialogTypeTitle) {
          title.value += dialogTypeTitle;
        } else {
          if (routerPage.value) {
            title.value += t(`route.${routerPage.value}`);
          }
        }
      }
    }

    isModal.value = true;
    nextTick(() => {
      const oBox = document.getElementById('basic-modal');
      const oBar = document.getElementById('basic-modal-bar');

      const closeBtn: any = document.querySelector('.n-dialog__close');

      if (closeBtn) {
        closeBtn.blur();
      }

      startDrag(oBar, oBox);
    });
  }

  function closeModal() {
    isModal.value = false;
    debounce(() => {
      subLoading.value = false;
    }, 300);
    emit('on-close');
  }

  function onCloseModal() {
    isModal.value = false;
    emit('on-close');
  }

  function handleSubmit() {
    subLoading.value = true;
    emit('on-ok');
  }

  const modalMethods: ModalMethods = {
    setProps,
    openModal,
    closeModal,
    setSubLoading,
  };

  const instance = getCurrentInstance();
  if (instance) {
    emit('register', modalMethods);
  }
</script>

<style lang="less">
  .cursor-move {
    cursor: move;
  }
</style>
